#include "file_transfer.h"
#include "logger.h"
#include <iostream>
#include <cstring>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string>
#include <vector>
#include <algorithm>
#include <iomanip>
#include <vector>
#include <algorithm>

const char *SERVER_IP = "192.168.247.134";
const int PORT = 8080;

void display_response(const std::string &response){
    // 检查状态码
    if (response.size() >= 3 && isdigit(response[0]) && isdigit(response[1]) && isdigit(response[2]))
    {
        std::string status_code = response.substr(0, 3);
        std::string message = response.substr(3);

        // 移除开头的空格和破折号
        while (!message.empty() && (message[0] == ' ' || message[0] == '-'))
        {
            message.erase(0, 1);
        }

        // 多行响应
        if (message.find('\n') != std::string::npos)
        {
            std::cout << "Server response (" << status_code << "):\n";
                      //<< message << "\n";
            // 按行分割并显示
            std::istringstream iss(message);
            std::string line;
            while (std::getline(iss, line))
            {
                // 移除可能的 \r
                if (!line.empty() && line[line.size() - 1] == '\r')
                {
                    line.pop_back();
                }
                std::cout << line << "\n";
            }
        }
        else
        {
            std::cout << "Server (" << status_code << "): " << message << "\n";
        }
    }
    else
    {
        // 非标准响应
        std::cout << "Server: " << response << "\n";
    }
}

int main(int argc, char *argv[]){
    //创建与初始化日志
    Logger::init("client.log", LogLevel::INFO);
    // 命令行模式
    if (argc >= 4)
    {
        std::string command = argv[1];
        std::string local_path = argv[2];
        std::string remote_path = argv[3];

        int sock = socket(AF_INET, SOCK_STREAM, 0);
        if (sock == -1)
        {
            Logger::error("Socket creation error: " + std::string(strerror(errno)));
            return 1;
        }

        sockaddr_in server_addr{};
        server_addr.sin_family = AF_INET;
        server_addr.sin_port = htons(PORT);
        inet_pton(AF_INET, SERVER_IP, &server_addr.sin_addr);

        if (connect(sock, (sockaddr *)&server_addr, sizeof(server_addr)))
        {
            Logger::error("Connect error: " + std::string(strerror(errno)));
            close(sock);
            return 1;
        }

        Logger::info("Connected to server: " + std::string(SERVER_IP) + ":" + std::to_string(PORT));

        // 接收欢迎消息
        char welcome[1024];
        ssize_t n = recv(sock, welcome, sizeof(welcome), 0);
        if (n > 0)
        {
            welcome[n] = '\0';
            Logger::info("Server: " + std::string(welcome));
        }

        if (command == "upload")
        {
            upload_file(sock, local_path, remote_path);
        }
        else if (command == "download")
        {
            download_file(sock, remote_path, local_path);
        }
        else
        {
            Logger::error("Invalid command: " + command);
        }

        close(sock);
        return 0;
    }

    // 交互模式
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock == -1)
    {
        Logger::error("Socket creation error: " + std::string(strerror(errno)));
        return 1;
    }

    sockaddr_in server_addr{};
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(PORT);
    inet_pton(AF_INET, SERVER_IP, &server_addr.sin_addr);

    if (connect(sock, (sockaddr *)&server_addr, sizeof(server_addr)))
    {
        Logger::error("Connect error: " + std::string(strerror(errno)));
        close(sock);
        return 1;
    }

    Logger::info("Connected to server: " + std::string(SERVER_IP) + ":" + std::to_string(PORT));

    // 接收欢迎消息
    char welcome[1024];
    ssize_t n = recv(sock, welcome, sizeof(welcome), 0);
    if (n > 0)
    {
        welcome[n] = '\0';
        std::cout << welcome;
    }
    while (true)
    {
        std::cout << "ftp> ";
        std::string command;
        std::getline(std::cin, command);

        if (command.empty())
            continue;

        // 转换命令为大写
        std::string upper_command = command;
        std::transform(upper_command.begin(), upper_command.end(), upper_command.begin(),
                       [](unsigned char c)
                       { return std::toupper(c); });

        // 处理退出命令
        if (upper_command == "QUIT")
        {
            send(sock, "QUIT\r\n", 6, 0);
            char response[1024];
            n = recv(sock, response, sizeof(response), 0);
            if (n > 0)
            {
                response[n] = '\0';
                std::cout << response;
            }
            break;
        }

        // 发送命令
        command += "\r\n";
        if (send(sock, command.c_str(), command.size(), 0) != command.size())
        {
            Logger::error("Failed to send command");
            break;
        }

        // 接收响应
        std::string response;
        char buffer[4096];
        while ((n = recv(sock, buffer, sizeof(buffer), 0))) {
            if (n <= 0)
                break;
            response.append(buffer, n);

            // 检查是否收到完整响应（以\r\n结尾）
            if (response.size() >= 2 && response.substr(response.size() - 2) == "\r\n")
            {
                break;
            }

            // 检查多行响应结束（以三位数字空格开头的新行）
            if (response.size() >= 5)
            {
                size_t pos = response.find_last_of('\n');
                if (pos != std::string::npos && pos >= 4)
                {
                    if (isdigit(response[pos - 4]) &&
                        isdigit(response[pos - 3]) &&
                        isdigit(response[pos - 2]) &&
                        response[pos - 1] == ' ')
                    {
                        break;
                    }
                }
            }
        }
        
        if (n <= 0) {
            Logger::error("Connection closed by server");
            break;
        }
        
        // 移除结尾的\r\n
        if (response.size() >= 2 && response.substr(response.size() - 2) == "\r\n") {
            response = response.substr(0, response.size() - 2);
        }
        
        display_response(response);
    }

    close(sock);
    return 0;
}